﻿Public Class Form1

    Private Sub Form1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Click

    End Sub



    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Calender1.ViewPage(Calender.GetFirstDate(Now))

    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Label1.Dispose()
        Label1.Update()
    End Sub


End Class

'The calendar class, when using it set its Width to exactly 700 
'and the height to about 700 for best result
Public Class Calender
    Inherits UserControl

    'Menus is used to store which things that is opened, 
    'notes in the date page or dates in the calender page
    Private Menus() As String

    'The current type of page that is open(this is case sensative)
    'Calender(it's spelt wrong) or Date 
    Private Page As String

    'Box is the picturebox that show the calendar, 
    'it's docked to the calendar class on load so the only method that should 
    'be used is the Image one ie. Box.Image = ... or ... = Box.Image
    Private Box As PictureBox

    'A timer controling action that happens when you hold the mouse
    Private tmrHolding As Timer
    'What kind of action is the timer handeling
    Private Holding As String

    'collectAll and collectDate is storing the notes(which they get from the settings)
    'when a date is opened all notes for that day are copied from the collectAll 
    'to the collectDate
    Dim collectAll As New Collection
    Dim collectDate As New Collection

    'Base images that is loaded from recources, for some reason 
    'they won't work if we're reading from the recources right 
    'away so instead we convert the bitmaps to "normal" bitmaps 
    'on load.
    Private myBaseImageDouble As Bitmap
    Private myBaseImageLeft As Bitmap
    Private myBaseImageRight As Bitmap

    Public Sub New()
        LoadSettings()

        'Prepares everything with the Picturebox
        Box = New PictureBox
        Box.Parent = Me
        Box.Dock = DockStyle.Fill
        AddHandler Box.MouseDown, AddressOf Calender_MouseDown
        AddHandler Box.MouseUp, AddressOf Calender_MouseUp

        'Prepares everything with the timer
        tmrHolding = New Timer
        AddHandler tmrHolding.Tick, AddressOf tmrHolding_Tick
        tmrHolding.Interval = 500


        'Prepare the  base images
        myBaseImageDouble = New Bitmap(700, 675)
        Using g As Graphics = Graphics.FromImage(myBaseImageDouble)
            g.DrawImageUnscaledAndClipped(My.Resources.DoubleTurn, New Rectangle(0, 0, myBaseImageDouble.Width, myBaseImageDouble.Height))
        End Using

        myBaseImageLeft = New Bitmap(700, 675)
        Using g As Graphics = Graphics.FromImage(myBaseImageLeft)
            g.DrawImageUnscaledAndClipped(My.Resources.LeftTurn, New Rectangle(0, 0, myBaseImageDouble.Width, myBaseImageDouble.Height))
        End Using

        myBaseImageRight = New Bitmap(700, 675)
        Using g As Graphics = Graphics.FromImage(myBaseImageRight)
            g.DrawImageUnscaledAndClipped(My.Resources.RightTurn, New Rectangle(0, 0, myBaseImageDouble.Width, myBaseImageDouble.Height))
        End Using
    End Sub

    'Used for going back to the main image, like the one without an opened note list in the Date page
    Private LastMainImage As Bitmap
    'Used for going bacl to the sub image, used for example when the user is writing anything
    Private LastSubImage As Bitmap
    'Specify what the user is writing, Title when writing the title and Content when writing in the content
    Private Writing As String

    'if this is true the calender won't response on most request, 
    'used when the user has to do something special(for instance, clicking on a messagebox button)
    Private Freeze As Boolean = False

    'This sub is handeling all the click events
    Private Sub Calender_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        'If this still is true at the end of the sub, close the Warning combobox.
        'This will mean if the user click outside the combobox, it will close,
        'just like a normal one...
        Dim closeWarningCombo As Boolean = True
        'If this still is true at the end of the sub, close the time Warning combobox.
        'This will mean if the user click outside the combobox, it will close,
        'just like a normal one...
        Dim closeWarningTimeCombo As Boolean = True

        'If the calendar have been freezed, to a few special things and then Exit 
        'to prevent other 'normal' actions
        If Freeze = True Then
            'Go through all buttons in a messagebox, if no messagebox is open this 
            'will be passed cause of the lack of buttons
            For i As Integer = 0 To myButtonLoc.Length - 1
                'Check if the mouseclick is in the button's rectangle
                If e.X >= myButtonLoc(i).X And e.X <= myButtonLoc(i).X + myButtonLoc(i).Width And e.Y >= myButtonLoc(i).Y And e.Y <= myButtonLoc(i).Y + myButtonLoc(i).Height Then
                    'set the buttonresult to the correct button, thil will get handled in the showMSG function.
                    buttonresult = i
                    Exit For
                End If
            Next

            'Nothing else then special stuff is allowed when the calendar is frozen
            Exit Sub
        End If

        'The right bottom corner, used to turn the page 'forward'(shouldn't be allowed on Date view)
        If e.X >= Me.Width - 50 And e.Y > Me.Height - 50 And Page <> "Date" Then
            'Forward

            'In Calendar view, show the next calender view
            If Page = "Calender" Then
                ViewPage()
            End If

            'The left bottom corner, used to turn the page 'backward'
        ElseIf e.X <= 50 And e.Y > Me.Height - 50 Then
            'Back

            'In Date view, go back to calendar view
            If Page = "Date" Then
                ViewPage(myLastStartDate)
            ElseIf Page = "Calender" Then
                ViewPage(GetFirstDate(myLastStartDate.AddDays(-1)))
            End If

            'Functions for the calendar view
        ElseIf Page = "Calender" Then
            Dim xCoord, yCoord As Integer
            'Check which page the user is clicking on, page 1 or page 2. 
            'If the user is clicking in a margin it will remember it as page 0
            If e.X >= 25 And e.X <= 300 Then
                xCoord = 1
            ElseIf e.X >= 375 And e.X <= 675 Then
                xCoord = 2
            Else
                xCoord = 0
            End If


            'Retrieve the items Y position, 0 means the click is outside an item
            Dim result As Integer
            Math.DivRem(e.Y, 125, result)
            If result <= 25 Then
                yCoord = 0
            Else
                yCoord = Math.Floor(e.Y / 125) + 1
            End If

            'Check if the user clicked on an item by checking for valid X and Y values
            If xCoord > 0 And xCoord < 3 And yCoord > 0 And yCoord < 6 Then

                'Calculate the items's position in the Menus array and loads the correct text
                Dim pos As Integer = (xCoord - 1) * 5 + yCoord - 1
                Dim MenuText As String = Menus(pos)

                'If we have something here...
                If MenuText <> "" Then
                    'Split the type from the actualy content(the type is only the first letter)
                    Dim type As Char = MenuText(0)
                    MenuText = MenuText.Remove(0, 1)
                    Dim values() As String = MenuText.Split("|")

                    'Do different things depending on type
                    If type = "D" Then 'If it's a date
                        'Year = 0
                        'Month = 1
                        'Day = 2

                        'Loads all Notes for this date into the date collection
                        collectDate.Clear()
                        For i As Integer = 1 To collectAll.Count
                            Dim Note As Note = collectAll(i)
                            If Note.Time.Year = values(0) And Note.Time.Month = values(1) And Note.Time.Day = values(2) Then
                                'Same date. Add the Note

                                collectDate.Add(Note)
                            End If

                        Next

                        'Open the date page for this date
                        ViewDate(New Date(values(0), values(1), values(2)))
                    ElseIf type = "M" Then 'If it's a month
                        'Year = 0
                        'Month = 1
                    ElseIf type = "Y" Then 'If it's a year
                        'Year = 0
                    End If

                End If
            End If

            'Functions for the date view
        ElseIf Page = "Date" Then
            'Check if the click is inside the area of the time list
            If e.X >= 50 And e.X <= 300 And e.Y >= 175 And e.Y <= 650 Then
                'If so, calculate which of them and show the notes for that time
                Dim tSpanStart As Integer = Math.Floor((e.Y - 175) / 80)
                ViewNotes(tSpanStart)

                'Check if the user have clicked the createbutton, this is not the button the
                'user clicks when they want to create a new note, it's the button they click
                'when they've already typed all info in for the new note
                '
                'The reason WarningOpen has to be false is because the warning combobox will cover the Create button and therefor it shouldn't be clickable
            ElseIf e.X >= CreateButton.X And e.X <= CreateButton.X + CreateButton.Width And e.Y >= CreateButton.Y And e.Y <= CreateButton.Y + CreateButton.Height And WarningOpen = False Then
                'Create Note

                'Check if it's valid
                If Title = "" Or Title = "<Title>" Or Content = "" Or Content = "Write the content here..." Then
                    'Else show an error
                    ShowMSG("You need to specify the title and content of your note...", "Important Message", MessageBoxButtons.OK)
                Else
                    If Not (SelectedPriority = PriorityType.IMPORTANT And SelectedWarning = WarningType.None _
                    AndAlso ShowMSG("You're just going to create an IMPORTANT note without warning.", "Important Message", MessageBoxButtons.OKCancel) = DialogResult.Cancel) Then


                        'Add the new note, the time, priority and warnings need to be fixed when they are added in the choices
                        Dim Note As New Note(Title, Content, New Date(openedDay.Year, openedDay.Month, openedDay.Day, Hour, Minute, 0), New Priority(SelectedPriority), New Warning(SelectedWarning, SelectedTimeWarning))
                        collectDate.Add(Note)
                        collectAll.Add(Note)
                        SaveSettings()

                        'Reset values
                        Title = "<Title>"
                        Content = "Write the content here..."
                        Writing = ""
                        SelectedPriority = 0
                        ReDim PriorityLocs(-1)
                        CreateButton = New Rectangle(-1, -1, -1, -1)
                        WarningRect = New Rectangle(-1, -1, -1, -1)
                        WarningTimeRect = New Rectangle(-1, -1, -1, -1)
                        HourRectangle = New Rectangle(-1, -1, -1, -1)
                        MinuteRectangle = New Rectangle(-1, -1, -1, -1)
                        SelectedTimeWarning = 0
                        SelectedWarning = 0
                        Hour = 0
                        Minute = 0


                        'Update the whole date page
                        ViewDate()
                    End If
                End If


                'If the combobox is open, close it. If it's closed, open it.
            ElseIf e.X >= WarningRect.X And e.X <= WarningRect.X + WarningRect.Width And e.Y >= WarningRect.Y And e.Y <= WarningRect.Y + WarningRect.Height Then
                WarningOpen = Not WarningOpen
                closeWarningCombo = False
                CreateNote()

                'If the combobox is open, close it. If it's closed, open it.
            ElseIf e.X >= WarningTimeRect.X And e.X <= WarningTimeRect.X + WarningTimeRect.Width And e.Y >= WarningTimeRect.Y And e.Y <= WarningTimeRect.Y + WarningTimeRect.Height Then
                WarningTimeOpen = Not WarningTimeOpen
                closeWarningTimeCombo = False
                CreateNote()


                'If the user is interacting with the hour box
            ElseIf e.X >= HourRectangle.X And e.X <= HourRectangle.X + HourRectangle.Width And e.Y >= HourRectangle.Y And e.Y <= HourRectangle.Y + HourRectangle.Height Then

                'Retrieve the Y offset inside the rectangle
                Dim Y As Integer = e.Y - HourRectangle.Y

                'If it's the top part, increase the hours if possible
                If Y < HourRectangle.Height / 2 And Hour <> 23 Then
                    Hour += 1
                    CreateNote()
                    Holding = "Hour+"
                    tmrHolding.Start()

                    'If it's the bottom part, decrease the hours if possible
                ElseIf Y >= HourRectangle.Height / 2 And Hour <> 0 Then
                    Hour -= 1
                    CreateNote()
                    Holding = "Hour-"
                    tmrHolding.Start()
                End If

                'If the user is interacting with the minute box
            ElseIf e.X >= MinuteRectangle.X And e.X <= MinuteRectangle.X + MinuteRectangle.Width And e.Y >= MinuteRectangle.Y And e.Y <= MinuteRectangle.Y + MinuteRectangle.Height Then

                'Retrieve the Y offset inside the rectangle
                Dim Y As Integer = e.Y - MinuteRectangle.Y

                'If it's the top part, increase the minutes if possible
                If Y < MinuteRectangle.Height / 2 Then
                    If Minute = 59 And Hour <> 23 Then
                        Minute = 0
                        Hour += 1
                        CreateNote()
                        Holding = "Minute+"
                        tmrHolding.Start()
                    ElseIf Minute <> 59 Then
                        Minute += 1
                        CreateNote()
                        Holding = "Minute+"
                        tmrHolding.Start()
                    End If


                   

                    'If it's the bottom part, decrease the minutes if possible
                Else
                    If Minute = 0 And Hour <> 0 Then
                        Hour -= 1
                        Minute = 59
                        CreateNote()
                        Holding = "Minute-"
                        tmrHolding.Start()
                    ElseIf Minute <> 0 Then
                        Minute -= 1
                        CreateNote()
                        Holding = "Minute-"
                        tmrHolding.Start()
                    End If
                End If



                'Else if the user clicked on page 2(margins doesn't count)
            ElseIf e.X >= 375 And e.X <= 675 Then
                'Go through all the notes, if there isn't any this will be skipped cause of the lack of elements in the array
                For Each item As String In Menus

                    'Split it up
                    '0 = ID
                    '1 = Top Y
                    '2 = Bottom Y
                    Dim splt() As String = item.Split("|")

                    'Check if the user clicked the button
                    If e.Y >= splt(1) And e.Y < splt(2) Then

                        'If this item is outside the range of the collection it means
                        'it's the create button(the one the user clicks before filling the info in)
                        If splt(0) > collectDate.Count Then
                            'The create new button

                            'Set writing type
                            Writing = "Title"
                            'Create the design for the creation
                            CreateNote()
                            Exit For
                        Else
                            'Else just view the note
                            ViewNote(splt(0))
                            Exit For
                        End If

                    End If
                Next

                'Check all priority rectangles
                For i As Integer = 0 To PriorityLocs.Length - 1
                    'If the user clicked in it...
                    If e.X >= PriorityLocs(i).X And e.X <= PriorityLocs(i).X + PriorityLocs(i).Width And e.Y >= PriorityLocs(i).Y And e.Y <= PriorityLocs(i).Y + PriorityLocs(i).Height Then
                        'set SelectedPriority to the clicked priority
                        SelectedPriority = i
                        'Updated it...
                        CreateNote()
                        Exit For
                    End If
                Next

                'if the user is writing, change writing type if the user clicked on a text
                If Writing <> "" Then
                    If e.Y >= TitleTop And e.Y <= TitleBottom Then
                        'Title
                        Writing = "Title"
                    ElseIf e.Y >= ContentTop Then
                        'Content
                        Writing = "Content"
                    End If
                End If

                'check if a menu in the warning combobox was clicked
                If WarningOpen = True Then
                    For i As Integer = 1 To 4
                        If e.X >= WarningRect.X And e.X <= WarningRect.X + WarningRect.Width And e.Y >= WarningRect.Y + WarningRect.Height * i And e.Y <= WarningRect.Y + WarningRect.Height * (i + 1) Then
                            SelectedWarning = i - 1
                            closeWarningCombo = False
                            CreateNote()

                            Exit For
                        End If

                    Next
                End If

                'check if a menu in the time warning combobox was clicked
                If WarningTimeOpen = True Then
                    For i As Integer = -11 To -1
                        If e.X >= WarningTimeRect.X And e.X <= WarningTimeRect.X + WarningTimeRect.Width And e.Y >= WarningTimeRect.Y + WarningTimeRect.Height * i And e.Y <= WarningTimeRect.Y + WarningTimeRect.Height * (i + 1) Then
                            SelectedTimeWarning = i + 11
                            closeWarningTimeCombo = False
                            CreateNote()

                            Exit For
                        End If

                    Next
                End If
            End If






        End If

        'If the user clicked outside the combobox that was open
        If closeWarningCombo And WarningOpen Then
            WarningOpen = False
            CreateNote()
        End If

        'If the user clicked outside the combobox that was open
        If closeWarningTimeCombo And WarningTimeOpen Then
            WarningTimeOpen = False
            CreateNote()
        End If

    End Sub

    'This sub clears the holding variables
    Private Sub Calender_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
        If Holding <> "" Then
            tmrHolding.Interval = 500
            tmrHolding.Stop()
            Holding = ""
        End If
    End Sub

    'This timer is handling the mouse holding actions
    Private Sub tmrHolding_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs)
        'The more the user is holding, the faster the timer 
        'will tick, the timer starts at 500 and minumun is 25
        If tmrHolding.Interval * 0.75 >= 25 Then
            tmrHolding.Interval *= 0.75
        End If

        'Select the current action
        Select Case Holding
            Case "Hour+"
                'Increase the hours if possible
                If Hour <> 23 Then
                    Hour += 1
                    CreateNote()
                End If

            Case "Hour-"
                'Decrease the hours if possible
                If Hour <> 0 Then
                    Hour -= 1
                    CreateNote()
                End If
            Case "Minute+"
                'Increase the minutes if possible
                If Minute = 59 And Hour <> 23 Then
                    Minute = 0
                    Hour += 1
                    CreateNote()
                ElseIf Minute <> 59 Then
                    Minute += 1
                    CreateNote()
                End If

            Case "Minute-"
                'Decrease the minutes if possible
                If Minute = 0 And Hour <> 0 Then
                    Minute = 59
                    Hour -= 1
                    CreateNote()
                ElseIf Minute <> 0 Then
                    Minute -= 1
                    CreateNote()
                End If
        End Select
    End Sub




    'The top of the title string
    Private TitleTop As Integer
    'The bowwom of the title string
    Private TitleBottom As Integer
    'The top of the content string
    Private ContentTop As Integer
    'The rectangle storing the exact location of the CreateButton(the one after information has been filled)
    Private CreateButton As Rectangle = New Rectangle(-1, -1, -1, -1)

    ''' <summary>
    ''' View the list of notes for the specific time
    ''' </summary>
    ''' <param name="TimeSpanStart">The specific start time in hours of the day</param>
    ''' <remarks>View the list of notes for the specific time</remarks>
    Private Sub ViewNotes(ByVal TimeSpanStart As Integer)
        'Continues to draw from the main date image
        Using Img As Bitmap = LastMainImage.Clone, g As Graphics = Graphics.FromImage(Img)

            'resets the menus, this will be filled later in this sub
            ReDim Menus(-1)

            'used for storing locations to later be stored in the Menus array to 
            'be used to check if something has been clicked
            Dim top, bottom As Integer
            'the offset height from the top, this variable increases after each 
            'note-draw to place the next one directly below it
            Dim noteHeight As Integer = 0

            'If timeSpanStart is -1 it means we're only here to draw 
            'the 'Create new note' button(before the user have selected a time)
            If TimeSpanStart <> -1 Then
                'Declares a variable where we'll store the current note
                Dim Item As Note

                'Go through all the items
                For i As Integer = 1 To collectDate.Count

                    'retrieve the current item
                    Item = collectDate.Item(i)

                    'Check if the note is a part of the selected time
                    If Item.Time.Hour >= TimeSpanStart * 4 And Item.Time.Hour < TimeSpanStart * 4 + 4 Then

                        'Calculate the top for later
                        top = 50 + noteHeight

                        'Draw the note's header with it's font and color
                        g.DrawString(Item.Header, Item.Priority.Font, Item.Priority.Color, 375, top)

                        'Increase the noteHeghit acordingly
                        noteHeight += g.MeasureString(Item.Header, Item.Priority.Font).Height

                        'Calculates the bottom with the new noteHeight
                        bottom = 50 + noteHeight

                        'Adds a new element for the new item
                        ReDim Preserve Menus(Menus.Length)
                        'then we stores the ID|TOP|BOTTOM to be used later when we check if this item have been clicked
                        Menus(Menus.Length - 1) = i & "|" & top & "|" & bottom
                    End If
                Next
                'If atleast one Item have been printed we create a 25px space to the 'Create new note' button
                If noteHeight <> 0 Then
                    noteHeight += 25
                End If
            End If
            'Calculate the top for the 'Create new note' button
            top = 50 + noteHeight
            'Draw it
            g.DrawString("Create new note", GetFont(12), Brushes.Black, 375, top)
            'Increase the noteHeight
            noteHeight += g.MeasureString("Create new note", GetFont(12)).Height
            'And stores the button
            bottom = 50 + noteHeight
            'Adds a new element for the button
            ReDim Preserve Menus(Menus.Length)
            'And add it to the menus
            Menus(Menus.Length - 1) = collectDate.Count + 1 & "|" & top & "|" & bottom

            'Saves the image for later
            LastSubImage = Img.Clone
            'And also loads it into the picturebox
            Box.Image = Img.Clone
        End Using
    End Sub
    ''' <summary>
    ''' View a single note
    ''' </summary>
    ''' <param name="itemID">The ID of the note to view</param>
    ''' <remarks>View a single note</remarks>
    Private Sub ViewNote(ByVal itemID As Integer)
        'Loads the correct note into an variable called Item
        Dim Item As Note = collectDate.Item(itemID)

        'Continues to draw on the sub image
        Using Img As Bitmap = LastSubImage.Clone, g As Graphics = Graphics.FromImage(Img)
            'calculates the Y value for the line, the rest is drawn compared to the line
            Dim yVal As Integer = Menus(Menus.Length - 1).Split("|")(2) + 70
            'Write the line
            g.DrawLine(Pens.Black, 400, yVal, 675, yVal)

            'Calculate the header size
            Dim strSize As SizeF = g.MeasureString("View Note", GetFont(24))
            'Draw the header
            g.DrawString("View Note", GetFont(24), Brushes.Black, 375 + (300 - strSize.Width) / 2, yVal - strSize.Height)

            'Calculate the sub header size
            strSize = g.MeasureString(Item.Header, GetFont(16))
            'Draw the sub header
            g.DrawString(Item.Header, GetFont(16), Brushes.Black, 375 + (300 - strSize.Width) / 2, yVal + 5)

            'change the Y value to be a bit below the headeres
            yVal += 25 + strSize.Height

            'Loads the text
            Dim str As String = Item.Content

            'Wraps the text at a width of 300px using the WrapText sub
            WrapText(str, 300)

            'Draw the content
            g.DrawString(str, GetFont(8), Brushes.Black, 375, yVal)

            'Show the image in the picturebox
            Box.Image = Img.Clone
        End Using
    End Sub

    'The current title the user has written
    Private Title As String = "<Title>"
    'The current content the user has written
    Private Content As String = "Write the content here..."
    'The currently selected priority
    Private SelectedPriority As Integer = 0
    'The location of the priority selections
    Private PriorityLocs(-1) As Rectangle
    'The rectangle storing the warning combobox
    Private WarningRect As Rectangle = New Rectangle(-1, -1, -1, -1)
    'The currently selected warning
    Private SelectedWarning As Integer = 0
    'If the warning combobox is open
    Private WarningOpen As Boolean = False
    'The rectangle storing the warning time combobox
    Private WarningTimeRect As Rectangle = New Rectangle(-1, -1, -1, -1)
    'The currently selected time warning
    Private SelectedTimeWarning As Integer = 0
    'If the time warning combobox is open
    Private WarningTimeOpen As Boolean = False
    'The rectangle storing the hours
    Private HourRectangle As Rectangle
    'The selected hour
    Private Hour As Integer = 0
    'The rectangle storing the minutes
    Private MinuteRectangle As Rectangle
    'The selected minute
    Private Minute As Integer = 0
    ''' <summary>
    ''' View everything that is needed when the user creates a new Note
    ''' </summary>
    ''' <remarks>View everything that is needed when the user creates a new Note</remarks>
    Private Sub CreateNote()
        'Continues to draw on the sub image
        Using Img As Bitmap = LastSubImage.Clone, g As Graphics = Graphics.FromImage(Img)
            'calculates the Y value for the line, the rest is drawn compared to the line
            Dim yVal As Integer = Menus(Menus.Length - 1).Split("|")(2) + 70
            'Write the line
            g.DrawLine(Pens.Black, 400, yVal, 675, yVal)

            'Calculate the header size
            Dim strSize As SizeF = g.MeasureString("Create Note", GetFont(24))
            'Draw the header
            g.DrawString("Create Note", GetFont(24), Brushes.Black, 375 + (300 - strSize.Width) / 2, yVal - strSize.Height)

            'Saves the title top location
            TitleTop = yVal + 5

            'Calculate the sub header size
            strSize = g.MeasureString(Title, GetFont(16))
            'Draw the sub header
            g.DrawString(Title, GetFont(16), Brushes.Black, 375 + (300 - strSize.Width) / 2, TitleTop)

            'Saves the title bottom location
            TitleBottom = TitleTop + strSize.Height

            'change the Y value to be a bit below the headeres
            yVal += 25 + strSize.Height

            'Saves the top of the content
            ContentTop = yVal

            'Loads the text
            Dim str As String = Content

            'Wraps the text at a width of 300px using the WrapText sub
            WrapText(str, 300, 500 - yVal)

            'Draw the content
            g.DrawString(str, GetFont(8), Brushes.Black, 375, yVal)


            'Draw a line seperating the options from the text writing
            g.DrawLine(New Pen(Color.Black, 1), 375, 525, 650, 525)

            'Calculate the size of the create button
            strSize = g.MeasureString("Create", GetFont(16))
            'Saves its location
            CreateButton = New Rectangle(Me.Width - 25 - strSize.Width, Me.Height - 25 - strSize.Height, strSize.Width, strSize.Height)
            'Draw the create button
            g.DrawString("Create", GetFont(16), Brushes.Black, CreateButton.X, CreateButton.Y)

            'Print the priority options
            g.DrawString("Select priority:", GetFont(10), Brushes.Black, 375, CreateButton.Y - 60)

            'Prepare the array for the locations
            ReDim PriorityLocs(2)

            'Go through the 3 priorities
            For i As Integer = 0 To 2
                'Get the priority
                Dim myPriority As PriorityType = i

                'Calculate the x and y values
                Dim x As Integer = 400
                Dim y As Integer = CreateButton.Y - (2 - i) * 20

                'Draw the string
                g.DrawString(myPriority + 1 & ". " & myPriority.ToString, GetFont(8), Brushes.Black, x, y)

                'Calculate the position of the radiobutton
                PriorityLocs(i) = New Rectangle(x - 13, y + 1.5, 8, 8)

                'If this is the selected one fill the radiobutton
                If i = SelectedPriority Then
                    g.FillEllipse(New SolidBrush(Color.FromArgb(56, 185, 53)), PriorityLocs(i))
                End If

                'Draw the actual radiobutton
                g.DrawEllipse(New Pen(Color.Black, 1), PriorityLocs(i))


            Next






            '--- Print hours ----

            'Calculate the positions of the two boxes
            HourRectangle = New Rectangle(CreateButton.X - 120, 625, 40, 18)
            MinuteRectangle = New Rectangle(HourRectangle.X + HourRectangle.Width + 20, HourRectangle.Y, HourRectangle.Width, HourRectangle.Height)

            'Draw a colon inbetween the hours and minutes
            str = ":"
            strSize = g.MeasureString(str, GetFont(12))
            g.DrawString(str, GetFont(12), Brushes.Black, HourRectangle.X + HourRectangle.Width + (MinuteRectangle.X - (HourRectangle.X + HourRectangle.Width) - strSize.Width) / 2, HourRectangle.Y + (HourRectangle.Height - strSize.Height) / 2)

            'Draw a time header
            str = "Select time:"
            strSize = g.MeasureString(str, GetFont(10))
            g.DrawString(str, GetFont(10), Brushes.Black, HourRectangle.X + (MinuteRectangle.X + MinuteRectangle.Width - HourRectangle.X - strSize.Width) / 2, HourRectangle.Y - strSize.Height - 2)

            'Draw the hour box
            g.DrawRectangle(Pens.Black, HourRectangle)
            g.DrawString("+", GetFont(8), Brushes.Black, HourRectangle.X + HourRectangle.Width - 8, HourRectangle.Y - 3)
            g.DrawString("-", GetFont(8), Brushes.Black, HourRectangle.X + HourRectangle.Width - 7, HourRectangle.Y + HourRectangle.Height - 12)
            g.DrawLine(Pens.Black, HourRectangle.X + HourRectangle.Width - 9, HourRectangle.Y, HourRectangle.X + HourRectangle.Width - 9, HourRectangle.Y + HourRectangle.Height)

            'Draw the hours
            g.DrawString(AddZeroes(Hour), GetFont(8), Brushes.Black, HourRectangle.X + 3, HourRectangle.Y + 3)

            'Modify the HourRectangle to only include the + and -
            HourRectangle = New Rectangle(HourRectangle.X + HourRectangle.Width - 9, HourRectangle.Y, 9, HourRectangle.Height)


            '--- Print minutes ---

            'Draw the minute box
            g.DrawRectangle(Pens.Black, MinuteRectangle)
            g.DrawString("+", GetFont(8), Brushes.Black, MinuteRectangle.X + MinuteRectangle.Width - 8, MinuteRectangle.Y - 3)
            g.DrawString("-", GetFont(8), Brushes.Black, MinuteRectangle.X + MinuteRectangle.Width - 7, MinuteRectangle.Y + MinuteRectangle.Height - 12)
            g.DrawLine(Pens.Black, MinuteRectangle.X + MinuteRectangle.Width - 9, MinuteRectangle.Y, MinuteRectangle.X + MinuteRectangle.Width - 9, MinuteRectangle.Y + MinuteRectangle.Height)

            'Draw the minute
            g.DrawString(AddZeroes(Minute), GetFont(8), Brushes.Black, MinuteRectangle.X + 3, MinuteRectangle.Y + 3)

            'Modify the MinuteRectangle to only include the + and -
            MinuteRectangle = New Rectangle(MinuteRectangle.X + MinuteRectangle.Width - 9, MinuteRectangle.Y, 9, MinuteRectangle.Height)






            'Print out the warnings



            'Calculate the location and size of the WarningRect
            WarningRect = New Rectangle(CreateButton.X - 120, CreateButton.Y - 60, 80, 18)


            Dim names(3) As String
            Dim wName As WarningType
            'Loop through the warning types and save it in the names array
            For i As Integer = 0 To 3
                wName = i
                'Extract the string from the warning type and store it for later use
                names(i) = wName.ToString.Replace("_", " ").Replace("and", "&")
            Next

            'create the combobox
            CreateCombobox(g, WarningRect, names, SelectedWarning, WarningOpen, False, True)



            'Calculate the location and size of the WarningTimeRect
            WarningTimeRect = New Rectangle(WarningRect.X + WarningRect.Width + 10, WarningRect.Y, 120, WarningRect.Height)


            'Write some headers. The reason they all are written here is to make sure everyone has the same Y value
            strSize = g.MeasureString("Warning type:", GetFont(10))
            g.DrawString("Warning type:", GetFont(10), Brushes.Black, WarningRect.X - 4, WarningRect.Y - strSize.Height - 4)
            g.DrawString("Warning time:", GetFont(10), Brushes.Black, WarningTimeRect.X + 15, WarningRect.Y - strSize.Height - 4)





            ReDim names(10)
            Dim wtName As WarningTime
            For i As Integer = 0 To 10
                If SelectedWarning <> 0 Then
                    wtName = i
                    'Extract the string from the warning time and store it for later use
                    names(i) = wtName.ToString.Replace("_", " ").TrimStart
                Else
                    names(i) = "No warning selected"
                End If
            Next
            'create the combobox
            CreateCombobox(g, WarningTimeRect, names, SelectedTimeWarning, WarningTimeOpen And SelectedWarning <> 0, True, SelectedWarning <> 0)








            'Show the image in the picturebox
            Box.Image = Img.Clone
        End Using
    End Sub

    ''' <summary>
    ''' Loads all the settings
    ''' </summary>
    ''' <remarks>Loads all the settings</remarks>
    Private Sub LoadSettings()
        If My.Settings.Notes Is Nothing Then
            My.Settings.Notes = New Collection
            collectAll = New Collection
        Else
            collectAll = My.Settings.Notes
        End If
    End Sub

    ''' <summary>
    ''' Saves all the settings
    ''' </summary>
    ''' <remarks>Saves all the settings</remarks>
    Private Sub SaveSettings()
        If collectAll Is Nothing Then
            collectAll = New Collection
            My.Settings.Notes = New Collection
        Else
            My.Settings.Notes = collectAll
        End If
        My.Settings.Save()
    End Sub





    'The current date that is opened, stored so we can update the date page
    Private openedDay As Date = Now
    ''' <summary>
    ''' Used to update the date page
    ''' </summary>
    ''' <remarks>Used to update the date page</remarks>
    Private Sub ViewDate()
        ViewDate(openedDay)
    End Sub
    ''' <summary>
    ''' Creates the date page for the current page
    ''' </summary>
    ''' <param name="opendate">The date to show</param>
    ''' <remarks>Creates the date page for the current page</remarks>
    Private Sub ViewDate(ByVal opendate As Date)
        'Stores the current date if we want to update the date page
        openedDay = opendate
        'Clears the menus, will be filled in the ViewNotes sub
        ReDim Menus(-1)
        'Sets the page type to Date
        Page = "Date"

        'Begin to draw a new image
        Using Img As Bitmap = myBaseImageLeft.Clone, g As Graphics = Graphics.FromImage(Img)
            'draw a white background
            'g.FillRectangle(Brushes.White, New Rectangle(0, 0, Img.Width, Img.Height))
            'draw a line in the middle between the pages
            'g.DrawLine(Pens.Black, 350, 25, 350, Img.Height - 25)

            'Declare a variable used to calculate sizes of texts
            Dim strSize As SizeF
            'Retrieves the Name of the current Month
            Dim mName As Months = opendate.Month
            'Creates the first header
            Dim str As String = GetDateTitle(opendate) & " " & mName.ToString

            'Declares a variable to keep track of where to put the text
            Dim height As Integer
            'Calculate the height of the first header
            strSize = g.MeasureString(str, GetFont(18))
            'Calculate the height(Y value)
            height = 75 - strSize.Height / 2
            'Draw the first header
            g.DrawString(str, GetFont(18), Brushes.Black, 25 + (300 - strSize.Width) / 2, height)
            'Increase the height(Y value) so the text isn't placed on the top of each other
            height += strSize.Height / 2

            'Get the text for the second header
            str = opendate.Year
            'Calculate the size
            strSize = g.MeasureString(str, GetFont(20))
            'Change the height(Y value) acordingly
            height += strSize.Height / 2
            'Draw the second header
            g.DrawString(str, GetFont(20), Brushes.Black, 25 + (300 - strSize.Width) / 2, height)

            'Go through the day with steps of 4 hours to receive 4 hours span
            For i As Integer = 0 To 23 Step 4
                'Draw a line
                g.DrawLine(Pens.Black, 50, 175 + i * 20, 300, 175 + i * 20)
                'Calcualte the header for the time span...
                str = AddZeroes(i) & ":00 to " & AddZeroes(i + 2) & ":59"
                '...and its size...
                strSize = g.MeasureString(str, GetFont(8))

                '...to then draw it
                g.DrawString(str, GetFont(8), Brushes.Black, 50, 175 + i * 20 - strSize.Height)


                'Used to store the current note in
                Dim Item As Note
                'Stores the current height, used so the notes won't be placed on top of each other
                Dim noteHeight As Integer = 0
                'Counts the number of notes that doesn't fit
                Dim itemCount As Integer = 0
                'Counts the number of important notes that doesn't fit
                Dim importantCount As Integer = 0

                'Go through all the notes
                For j As Integer = 1 To collectDate.Count
                    'Loads the current note
                    Item = collectDate.Item(j)

                    'Check if the note is in the current timespan
                    If Item.Time.Hour >= i And Item.Time.Hour < i + 4 Then
                        'Check if there's room for this note
                        If noteHeight <= 30 Then
                            'If so draw the note
                            g.DrawString(Item.Header, Item.Priority.Font, Item.Priority.Color, 60, 180 + i * 20 + noteHeight)
                            'And change noteHeight to place the next note on the correct place
                            noteHeight += g.MeasureString(Item.Header, Item.Priority.Font).Height
                        Else
                            'No rooms means we count notes that doesn't fit

                            'One more note doesn't fit
                            itemCount += 1

                            'If this is an important note, note that one more Important note doesn't fit
                            If Item.Priority.Type = PriorityType.IMPORTANT Then
                                importantCount += 1
                            End If
                        End If
                    End If
                Next
                'If we have at least one note
                If itemCount > 0 Then
                    'Stores the correct text depending on the number of notes and important notes
                    If importantCount = 0 Then
                        str = "+" & itemCount & " more..."
                    ElseIf itemCount - importantCount = 0 Then
                        str = "+" & importantCount & " IMPORTANT..."
                    Else
                        str = "+" & itemCount - importantCount & " normal and " & importantCount & " IMPORTANT..."
                    End If

                    'Print it out
                    g.DrawString(str, GetFont(8), Brushes.Green, 60, 180 + i * 20 + noteHeight)
                End If
            Next

            'Stores this as the main image
            LastMainImage = Img.Clone
            'View the notes for timespan -1, which means we just shows the 'Create new note' button
            'In the ViewNotes sub the picturebox will receive the image so we doesn't need to set it here
            ViewNotes(-1)
        End Using
    End Sub



    'The buttons in a messagebox, could be maximum 3
    Private myButtons(-1) As DialogResult
    'The location of the buttons in a messagebox, could be maximum 3
    Private myButtonLoc(-1) As Rectangle
    'The result of a messagebox
    Private buttonresult As Integer

    ''' <summary>
    ''' Show a messagebox in the calendar
    ''' </summary>
    ''' <param name="Message">The message</param>
    ''' <param name="Caption">The caption</param>
    ''' <param name="Buttons">The buttons that the user could choose between</param>
    ''' <returns>Return the button that was pressed</returns>
    ''' <remarks>Show a messagebox in the calendar, works like a normal messagebox.</remarks>
    Private Function ShowMSG(ByVal Message As String, ByVal Caption As String, ByVal Buttons As MessageBoxButtons) As DialogResult
        'Stores the current image so we can revert to it later
        Dim beforeMSG As Bitmap = Box.Image.Clone

        'The location where the messagebox will be shown, this is currrently static
        Dim location As New Rectangle((Me.Width - 300) / 2, 150, 300, 150)

        'Continue drawing on the current image
        Using Img As Bitmap = Box.Image.Clone, g As Graphics = Graphics.FromImage(Img)
            'Make a white background
            g.FillRectangle(Brushes.White, location)

            'Calculate the caption size
            Dim strSize As SizeF = g.MeasureString(Caption, GetFont(14))
            'Draw the caption background
            g.FillRectangle(Brushes.Gray, New Rectangle(location.X, location.Y, location.Width, strSize.Height + 15))

            'Draw the Caption
            g.DrawString(Caption, GetFont(14), Brushes.Black, location.X + 10, location.Y + 10)

            'Draw a border around the messagebox
            g.DrawRectangle(New Pen(Color.Black, 5), location)

            'Wrap the text so it'll fit
            WrapText(Message, location.Width - 30)
            'Draw the string
            g.DrawString(Message, GetFont(8), Brushes.Black, location.X + 20, location.Y + strSize.Height + 35)


            'Depending on the buttons, resize myButtons and myButtonLoc so all the 
            'buttons will fit, then fill myButtons with the correct buttons
            Select Case Buttons
                Case MessageBoxButtons.AbortRetryIgnore
                    ReDim myButtons(2)
                    ReDim myButtonLoc(2)
                    myButtons(0) = DialogResult.Abort
                    myButtons(1) = DialogResult.Retry
                    myButtons(2) = DialogResult.Ignore
                Case MessageBoxButtons.YesNoCancel
                    ReDim myButtons(2)
                    ReDim myButtonLoc(2)
                    myButtons(0) = DialogResult.Yes
                    myButtons(1) = DialogResult.No
                    myButtons(2) = DialogResult.Cancel
                Case MessageBoxButtons.YesNo
                    ReDim myButtons(1)
                    ReDim myButtonLoc(1)
                    myButtons(0) = DialogResult.Yes
                    myButtons(1) = DialogResult.No
                Case MessageBoxButtons.RetryCancel
                    ReDim myButtons(1)
                    ReDim myButtonLoc(1)
                    myButtons(0) = DialogResult.Retry
                    myButtons(1) = DialogResult.Cancel
                Case MessageBoxButtons.OKCancel
                    ReDim myButtons(1)
                    ReDim myButtonLoc(1)
                    myButtons(0) = DialogResult.OK
                    myButtons(1) = DialogResult.Cancel
                Case MessageBoxButtons.OK
                    ReDim myButtons(0)
                    ReDim myButtonLoc(0)
                    myButtons(0) = DialogResult.OK
            End Select

            'Generate a Y value for the buttons
            Dim y As Integer = g.MeasureString(Message, GetFont(8)).Height + location.Y + strSize.Height + 50
            'Generate the combined width of all the buttons, this is used when the X value is created
            Dim w As Integer = myButtons.Length * 50 + (myButtons.Length - 1) * 20

            'Loop through all the buttons
            For i As Integer = 0 To myButtons.Length - 1

                'Calculate the X value
                Dim x As Integer = location.X + (location.Width - w) / 2 + i * 70
                'Store the location of the button
                myButtonLoc(i) = New Rectangle(x, y, 50, 30)

                'Draw the button
                g.DrawRectangle(New Pen(Color.Black, 2), myButtonLoc(i))
                'Calculate text size
                strSize = g.MeasureString(myButtons(i).ToString, GetFont(8))
                'Draw the text
                g.DrawString(myButtons(i).ToString, GetFont(8), Brushes.Black, x + (myButtonLoc(i).Width - strSize.Width) / 2, y + (myButtonLoc(i).Height - strSize.Height) / 2)

            Next

            'Show the image in the picturebox
            Box.Image = Img.Clone
        End Using

        'Freeze the calendar to prevent other things
        Freeze = True
        'Set buttonresult to -1, this means no button has been pressed
        buttonresult = -1

        'Continue here until the click event have changed buttonresult
        While buttonresult = -1
            My.Application.DoEvents()
        End While

        'Unfreeze the calendar to allow other things again
        Freeze = False
        'Revert the image to how it were before
        Box.Image = beforeMSG.Clone

        'Set the return value
        ShowMSG = myButtons(buttonresult)
        'Reset the arrays
        ReDim myButtonLoc(-1)
        ReDim myButtons(-1)
    End Function

    'Stores the last end date viewed in a page, this is used to easily show the next page
    Private myLastEndDate As Date = Now.AddDays(-1)
    'Stores the last start date viewed in a page, this is used to go back
    'to the calendar view after viewing a date view
    Private myLastStartDate As Date = Now
    ''' <summary>
    ''' View the next calendar page
    ''' </summary>
    ''' <remarks>View the next calendar page</remarks>
    Public Sub ViewPage()
        ViewPage(myLastEndDate.AddDays(1))
    End Sub
    ''' <summary>
    ''' View the calendar page starting with the specified date
    ''' </summary>
    ''' <param name="startDate">The date to start with</param>
    ''' <remarks>View the calendar page starting with the specified date</remarks>
    Public Sub ViewPage(ByVal startDate As Date)
        'Set the page type to calendar
        Page = "Calender"

        'How many dates that have been showed, this is used to calculate 
        'the current date ie. by using startDate.AddDays(dateCount)
        Dim dateCount As Integer = 0
        'Which line to print on
        Dim currentLine As Integer = 1
        'If a month header have been displayed
        Dim newMonth As Boolean = False
        'If a year header have been displayed
        Dim newYear As Boolean = False
        'Used to calculate the size of texts
        Dim strSize As SizeF


        'Drawing a new image
        Using Img As Bitmap = myBaseImageDouble.Clone, g As Graphics = Graphics.FromImage(Img)
            'Draw a white background
            'g.FillRectangle(Brushes.White, New Rectangle(0, 0, Img.Width, Img.Height))

            'Prepare the Menus array for the 10 items
            ReDim Menus(9)
            'Draw a line between the pages
            'g.DrawLine(Pens.Black, 350, 25, 350, Img.Height - 25)

            'Loop until the whole calendar page have been drawn properly
            Do
                'New years are starting on a new page, therefor exit the loop if we're reaching a new year
                If startDate.AddDays(dateCount).Year <> startDate.Year Then
                    Exit Do
                End If




                'If the new year header haven't been drawed but we're at the first day in a year, print the year header
                If Not newYear And startDate.Month = 1 And startDate.Day = 1 Then
                    'Calculate the size...
                    strSize = g.MeasureString(startDate.Year, GetFont(50))
                    '...and draw the year header
                    g.DrawString(startDate.Year, GetFont(50), Brushes.Black, GetWidth(currentLine) + (300 - strSize.Width) / 2, GetHeight(currentLine) + (200 - strSize.Height) / 2)
                    'Tell the program we don't want to draw the header again
                    newYear = True
                    'Add the year to the Menus array for later use(this is currently not used).
                    Menus(currentLine - 1) = "Y" & startDate.Year
                    'The new year header takes a whole page, therefore add 4 lines extra
                    currentLine += 4

                    'If we haven't drawn a new month header but are at the first day of the month, then draw the header.
                ElseIf Not newMonth And startDate.AddDays(dateCount).Day = 1 Then
                    'We don't want the new month header to be last on the second page
                    If dateCount >= 8 Then
                        Exit Do
                        ' Not last on the first page either
                    ElseIf currentLine = 4 Or currentLine = 5 Then
                        'Here we set current line to 6 and then just restart the loop
                        currentLine = 6
                        Continue Do
                    Else
                        'If it isn't at the top of a page, then increase the currentline to make a space before the month header
                        If currentLine <> 1 And currentLine <> 6 Then
                            currentLine += 1
                        End If
                        'Retrieve the name of the month
                        Dim mName As Months = startDate.AddDays(dateCount).Month
                        'Calculate the text size of it
                        strSize = g.MeasureString(mName.ToString, GetFont(24))

                        'And draw it to the image
                        g.DrawString(mName.ToString, GetFont(24), Brushes.Black, GetWidth(currentLine) + (300 - strSize.Width) / 2, GetHeight(currentLine) + (100 - strSize.Height) / 2)
                        'Add the month to the Menus array for later use(this is currently not used).
                        Menus(currentLine - 1) = "M" & startDate.AddDays(dateCount).Year & "|" & startDate.AddDays(dateCount).Month

                        'Make sure we don't draw the header again
                        newMonth = True
                    End If
                Else
                    'Draw the date
                    g.DrawString(GetDateTitle(startDate.AddDays(dateCount)), GetFont(16), Brushes.Black, GetWidth(currentLine), GetHeight(currentLine))
                    strSize = g.MeasureString(GetDateTitle(startDate.AddDays(dateCount)), GetFont(16))





                    'Used to store the current note in
                    Dim Item As Note
                    'Stores the current height, used so the notes won't be placed on top of each other
                    Dim noteHeight As Integer = 0
                    'Counts the number of notes that doesn't fit
                    Dim itemCount As Integer = 0
                    'Counts the number of important notes that doesn't fit
                    Dim importantCount As Integer = 0

                    'Go through all the notes
                    For i As Integer = 1 To collectAll.Count
                        'Loads the current note
                        Item = collectAll.Item(i)

                        'Check if the note is in the current timespan
                        If Item.Time.Year = startDate.AddDays(dateCount).Year And Item.Time.Month = startDate.AddDays(dateCount).Month And Item.Time.Day = startDate.AddDays(dateCount).Day Then
                            'Check if there's room for this note

                            If noteHeight <= 75 - strSize.Height Then
                                'If so draw the note
                                g.DrawString(Item.Header, Item.Priority.Font, Item.Priority.Color, GetWidth(currentLine) + 20, GetHeight(currentLine) + noteHeight + strSize.Height)
                                'And change noteHeight to place the next note on the correct place
                                noteHeight += g.MeasureString(Item.Header, Item.Priority.Font).Height
                            Else
                                'No rooms means we count notes that doesn't fit

                                'One more note doesn't fit
                                itemCount += 1

                                'If this is an important note, note that one more Important note doesn't fit
                                If Item.Priority.Type = PriorityType.IMPORTANT Then
                                    importantCount += 1
                                End If
                            End If
                        End If
                    Next
                    'If we have at least one note
                    If itemCount > 0 Then
                        Dim str As String
                        'Stores the correct text depending on the number of notes and important notes
                        If importantCount = 0 Then
                            str = "+" & itemCount & " more..."
                        ElseIf itemCount - importantCount = 0 Then
                            str = "+" & importantCount & " IMPORTANT..."
                        Else
                            str = "+" & itemCount - importantCount & " normal and " & importantCount & " IMPORTANT..."
                        End If

                        'Print it out
                        g.DrawString(str, GetFont(8), Brushes.Green, GetWidth(currentLine) + 20, GetHeight(currentLine) + noteHeight + strSize.Height)
                    End If








                    'Adds the date to the menus array so we later on can click it
                    Menus(currentLine - 1) = "D" & startDate.AddDays(dateCount).Year & "|" & startDate.AddDays(dateCount).Month & "|" & startDate.AddDays(dateCount).Day

                    'Stores the date as the last date so we easy can turn the pages
                    myLastEndDate = startDate.AddDays(dateCount)

                    'Increase the number of dates so we pick a new date next time
                    dateCount += 1
                End If
                'Just for testing
                'g.DrawRectangle(Pens.Red, New Rectangle(GetWidth(currentLine), GetHeight(currentLine), 300, 100))

                'Increases the line by 1 so we draw on the next line the next time
                currentLine += 1
            Loop Until currentLine >= 11 'End if we've drawn all the lines

            'Calculate the size for the month footer
            strSize = g.MeasureString(GetMonthFooter(startDate, myLastEndDate), GetFont(12))
            'Draw the month footer
            g.DrawString(GetMonthFooter(startDate, myLastEndDate), GetFont(12), Brushes.Black, Img.Width - 70 - strSize.Width, Img.Height - 20 - strSize.Height)

            'Calculate the size for the year footer
            strSize = g.MeasureString(startDate.Year, GetFont(12))
            'Draw the year month
            g.DrawString(startDate.Year, GetFont(12), Brushes.Black, 70, Img.Height - 20 - strSize.Height)

            'test
            'g.DrawRectangle(Pens.Red, New Rectangle(Me.Width - 50, Me.Height - 50, 50, 50))
            'g.DrawRectangle(Pens.Red, New Rectangle(0, Me.Height - 50, 50, 50))
            'test end

            'Show the image in the picturebox
            Box.Image = Img.Clone

        End Using

        'Store the startdate, this is used if we want to go back here after viewing the date page
        myLastStartDate = startDate

    End Sub


    'This sub is handeling all the keydown events
    Private Sub Calender_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
        'Make sure the calendar ism't frozen
        If Freeze = True Then
            Exit Sub
        End If

        'If it's the correct page and we're writing
        If Page = "Date" And (Writing = "Title" Or Writing = "Content") Then

            'retireve what the user just wrote
            Dim code As String = e.KeyCode.ToString

            'Remove NumPad to make the numpad button valid
            code = code.Replace("NumPad", "")

            'Fix the space
            If code = "Space" Then
                code = " "
            End If

            'If the user is writing to something that has the default value, remove it first
            If Title = "<Title>" And Writing = "Title" Then
                Title = ""
            ElseIf Content = "Write the content here..." And Writing = "Content" Then
                Content = ""
            End If

            'If the user pressed backspace, try to remove the last character
            If code = "Back" Then
                If Writing = "Title" Then
                    If Title.Length > 0 Then
                        'Remove the last character in the title
                        Title = Title.Remove(Title.Length - 1, 1)
                    End If
                Else
                    If Content.Length > 0 Then
                        'Remove the last character in the content
                        Content = Content.Remove(Content.Length - 1, 1)
                    End If
                End If

                'Reset the code so it won't try to write anything
                code = ""

                'If it's longer the two characters it means it's not valid, it could 
                'be enter and caps for example and this should be handled in other ways
            ElseIf code.Length > 2 Then
                Exit Sub

                'Ctrl-V = Paste
            ElseIf code = "V" And My.Computer.Keyboard.CtrlKeyDown Then
                If My.Computer.Clipboard.ContainsText Then
                    code = My.Computer.Clipboard.GetText
                Else
                    code = ""
                End If

                'Remove the D in the beginning of the numbers
            ElseIf code.Length = 2 AndAlso (code(0) = "D" And IsNumeric(code(1))) Then
                code = code.Remove(0, 1)

                'Convert to lowercase if needed
            ElseIf Not (My.Computer.Keyboard.CapsLock Xor My.Computer.Keyboard.ShiftKeyDown) Then
                code = code.ToLower
            End If

            'Try to add the code and then update the text using CreateNote()
            If (code & Title).Length <= 20 And Writing = "Title" Then
                Title &= code
                CreateNote()
            ElseIf (code & Content).Length <= 1000 And Writing = "Content" Then
                Content &= code
                CreateNote()
            Else
                'But if the text will get too long...

                'If empty, reset to default(this is only for pasting too big things)
                If Writing = "Title" And Title = "" Then
                    Title = "<Title>"
                ElseIf Writing = "Content" And Content = "" Then
                    Content = "Write the content here..."
                End If

                'Beep to alert the user
                Beep()
            End If



        End If
    End Sub





#Region "Shared stuff"

    ''' <summary>
    ''' This sub wraps the text at a certain width
    ''' </summary>
    ''' <param name="str">The text to wrap</param>
    ''' <param name="width">The width of a line</param>
    ''' <param name="height">The maximum height of all lines together</param>
    ''' <remarks>This sub wraps the text at a certain width, it currently always use the same font so if you need to use different fonts, add a font parameter.</remarks>
    Private Shared Sub WrapText(ByRef str As String, ByVal width As Integer, Optional ByVal height As Integer = -1)
        'Declares a variable for storing all lines
        Dim lines(-1) As String

        'We need a graphic so we could use MeasureString
        Using g As Graphics = Graphics.FromImage(New Bitmap(1, 1))

            'A loop to loop while the text is too wide
            While g.MeasureString(str, GetFont(8)).Width > width
                'The character we're currently at
                Dim count As Integer = 1

                'Find where to make the line break by searching for where the text will be too wide
                Do Until g.MeasureString(str.Substring(0, count), GetFont(8)).Width > width
                    count += 1
                Loop

                'Removes the line and add it to the line array instead
                ReDim Preserve lines(lines.Length)
                lines(lines.Length - 1) = str.Substring(0, count - 1)
                str = str.Remove(0, count - 1)
            End While


            'Stores the text that is left as a last line
            ReDim Preserve lines(lines.Length)
            lines(lines.Length - 1) = str
            str = ""

            'Go through each line and add them back to the string, but with a new line between each
            For Each line In lines

                If height <> -1 Then
                    If g.MeasureString(str & line & Environment.NewLine, GetFont(8)).Height > height Then
                        str &= "..."
                        Exit For
                    Else
                        str &= line & Environment.NewLine
                    End If
                Else
                    str &= line & Environment.NewLine
                End If
            Next
        End Using
    End Sub

    ''' <summary>
    ''' Returns a font in the specified size
    ''' </summary>
    ''' <param name="size">The size of the font</param>
    ''' <returns>Returns a font in the specified size</returns>
    ''' <remarks>Returns a font in the specified size</remarks>
    Private Shared Function GetFont(ByVal size As Integer) As Font
        'This function is used so one doesn't have to write so much 
        'each time. It also easier to change something for the whole calendar.
        Return New Font("Arial", size, FontStyle.Regular, GraphicsUnit.Point)
    End Function

    ''' <summary>
    ''' Returns the X value for the current calendar line
    ''' </summary>
    ''' <param name="line">The current calendar line</param>
    ''' <returns>Returns the X value for the current calendar line</returns>
    ''' <remarks>Returns the X value for the current calendar line</remarks>
    Private Shared Function GetWidth(ByVal line As Integer) As Integer
        'width of a page is 350 - 25 = 325
        Return 350 * Math.Floor((line - 1) / 5) + 25
    End Function

    ''' <summary>
    ''' Returns the Y value for the current calendar line
    ''' </summary>
    ''' <param name="line">The current calendar line</param>
    ''' <returns>Returns the Y value for the current calendar line</returns>
    ''' <remarks>Returns the Y value for the current calendar line</remarks>
    Private Shared Function GetHeight(ByVal line As Integer) As Integer
        Dim returnVal As Integer
        Math.DivRem(line - 1, 5, returnVal)

        'height of 'line' is 125 - 25 = 100
        returnVal = 125 * returnVal + 25
        Return returnVal
    End Function

    ''' <summary>
    ''' Modifies a string to show time properly
    ''' </summary>
    ''' <param name="value">The integer to use</param>
    ''' <returns>Returns teh new string</returns>
    ''' <remarks>Modifies a string to show time properly by adding a zero in the begining if it isn't 2 char long already.</remarks>
    Private Shared Function AddZeroes(ByVal value As Integer)
        If value.ToString.Length = 1 Then
            Return "0" & value
        Else
            Return value
        End If
    End Function

    ''' <summary>
    ''' Get the date title used in the calendar view
    ''' </summary>
    ''' <param name="d">The date to use</param>
    ''' <returns>Get the date title used in the calendar view</returns>
    ''' <remarks>Get the date title used in the calendar view</remarks>
    Private Shared Function GetDateTitle(ByVal d As Date) As String
        'Retrieve the day name
        Dim dName As DayOfWeek = d.DayOfWeek

        'Create the postfix depending on the day number
        Dim postfix As String
        Select Case d.Day
            Case 1, 21, 31
                postfix = "st"
            Case 2, 22
                postfix = "nd"
            Case 3, 23
                postfix = "rd"
            Case Else
                postfix = "th"
        End Select

        'Return the date title
        Return dName.ToString & " " & d.Day & postfix

    End Function

    ''' <summary>
    ''' Get the month footer
    ''' </summary>
    ''' <param name="startdate">The start date of the calendar page</param>
    ''' <param name="enddate">The end date of the calendar page</param>
    ''' <returns>Returns the month footer</returns>
    ''' <remarks>Get the month footer</remarks>
    Private Function GetMonthFooter(ByVal startdate As Date, ByVal enddate As Date) As String
        'Retrieve the start date name
        Dim startName As Months = startdate.Month

        'Check if the monts are the same
        If startdate.Month <> enddate.Month Then

            'If they are different, retruieve the end date name...
            Dim endName As Months = enddate.Month

            'And return both the months
            Return startName.ToString & " - " & endName.ToString
        Else

            'If they are the same just return the month
            Return startName.ToString
        End If
    End Function
    Private Enum Months
        January = 1
        February
        March
        April
        May
        June
        July
        August
        September
        October
        November
        December
    End Enum

    ''' <summary>
    ''' Draw a combobox, note that this doesn't create the click functionality.
    ''' </summary>
    ''' <param name="g">The graphic to draw with</param>
    ''' <param name="rect">The rectangle where the unopen combobox is located</param>
    ''' <param name="names">An array with all the names of the items in the list</param>
    ''' <param name="selected">The 0-based index of the selected item</param>
    ''' <param name="isOpen">If the combobox is open or not</param>
    ''' <param name="ListUp">True if the list is going upwards instead</param>
    ''' <param name="Enabled">If the combobox is enabled or not</param>
    ''' <remarks>Draw a combobox, note that this doesn't create the click functionality.</remarks>
    Private Shared Sub CreateCombobox(ByVal g As Graphics, ByVal rect As Rectangle, ByVal names() As String, ByVal selected As Integer, ByVal isOpen As Boolean, ByVal ListUp As Boolean, ByVal enabled As Boolean)
        'Set the line color depending on if the combobox is enabled or not
        Dim lineColor As Color
        If enabled = True Then
            lineColor = Color.Black
        Else
            lineColor = Color.Gray
        End If


        'The coordinates for the combobox arrow
        Dim points(2) As Point
        If Not (ListUp Xor isOpen) Then
            'If some of these is correct:
            'List Up and List is Open
            'List Down and List is Closed

            points(0) = New Point(rect.X + rect.Width - 14, rect.Y + rect.Height / 3)
            points(1) = New Point(rect.X + rect.Width - 4, rect.Y + rect.Height / 3)
            points(2) = New Point(rect.X + rect.Width - 9, rect.Y + rect.Height * 2 / 3)
        Else
            'If some of these is correct:
            'List Up and List is Closed
            'List Down and List is Open

            points(0) = New Point(rect.X + rect.Width - 14, rect.Y + rect.Height * 2 / 3)
            points(1) = New Point(rect.X + rect.Width - 4, rect.Y + rect.Height * 2 / 3)
            points(2) = New Point(rect.X + rect.Width - 9, rect.Y + rect.Height / 3)
        End If

        Dim str As String

        'Draw the combobox
        g.DrawRectangle(New Pen(lineColor), rect)
        'Draw the combobox arrow
        g.FillPolygon(New SolidBrush(lineColor), points)

        'If the combobox is open...
        Dim popDRect As Rectangle
        If isOpen Then
            'Calculate the area for the popdown rectangle and fill it white with a black border.
            popDRect = New Rectangle(rect.X, rect.Y + rect.Height * (ListUp + 1) + rect.Height * names.Length * ListUp, rect.Width, rect.Height * names.Length)
            g.FillRectangle(Brushes.White, popDRect)
            g.DrawRectangle(New Pen(lineColor), popDRect)
        End If


        'Loop through the items to write the text for them, -1 is the header. 
        'If isOpen is False it will loop to 0*names.Length*-1 -1 = -1 
        'If isOpen is True it will loop to -1*names.Length*-1 -1 = names.Length - 1
        For i As Integer = -1 To isOpen * names.Length * -1 - 1
            'If it's the header we want the selected warning type
            If i = -1 Then
                str = names(selected)
            Else
                'Else we pick the current one in the loop
                str = names(i)

                'If the current one in the loop is selected...
                If i = selected Then

                    '...paint the background of it blue.
                    g.FillRectangle(Brushes.Blue, New Rectangle(rect.X + 1, popDRect.Y + rect.Height * i + 1, rect.Width - 1, rect.Height - 1))
                End If
            End If


            'Draw the text
            g.DrawString(str, GetFont(8), New SolidBrush(lineColor), rect.X + 2, rect.Y + 3 + rect.Height * (((i = -1 And ListUp) + 1) * isOpen * (names.Length + 1) * ListUp * -1 + i + 1))

        Next
    End Sub

    ''' <summary>
    ''' Retrieve the start date of the page with the specified date in it
    ''' </summary>
    ''' <param name="d">The date it's searhing for</param>
    ''' <returns>Returns the start date of the page with the specified date in it</returns>
    ''' <remarks>Retrieve the start date of the page with the specified date in it</remarks>
    Public Shared Function GetFirstDate(ByVal d As Date) As Date
        'This is the first date of the year
        Dim yearStart As New Date(d.Year, 1, 1)
        'Counts through all the years
        Dim dateCount As Integer = 0
        'While it's still the same year, this loop shouldn't loop to the end or something have gotten wrong
        While yearStart.AddDays(dateCount).Year = yearStart.Year
            'Count number of lines, 10 lines per page
            Dim lineCount As Integer = 0
            'Stores the start date of this page
            Dim startDate As Date = yearStart.AddDays(dateCount)

            'Count 10 lines, then the page is done
            Do Until lineCount >= 10
                'If it is the first day in the year
                If yearStart.AddDays(dateCount).Month = 1 And yearStart.AddDays(dateCount).Day = 1 Then
                    'Add 5 lines for the year and 1 for the month
                    lineCount += 6

                    'If it isn't a new year but only a new month
                ElseIf yearStart.AddDays(dateCount).Day = 1 Then
                    If lineCount = 0 Or lineCount = 5 Then

                        'If the date is on the top of a page, only increase with 1 for the actual motnh
                        lineCount += 1
                    ElseIf lineCount = 3 Or lineCount = 4 Then

                        'If there's a month at the end of the first page, make it appear first on the second one
                        lineCount = 5

                    ElseIf lineCount = 8 Or lineCount = 9 Then

                        'If there's a new month at the end, this page is done and that month will be printed on next page
                        Exit Do
                    Else

                        'Else increase with 2, one for the month and one for the space before it
                        lineCount += 2
                    End If
                End If

                'Always increase one line for the date
                lineCount += 1
                'Increase dateCount to get the next date next time
                dateCount += 1
            Loop

            'Check if the date to search for is between the start and end dates, if so return it
            If d.Ticks >= startDate.Ticks And d.Ticks <= yearStart.AddDays(dateCount).Ticks Then
                Return startDate
            End If

        End While
        'This shouldn't happend...
        Return Nothing
    End Function

#End Region

#Region "Note stuff"
    ''' <summary>
    ''' A note
    ''' </summary>
    ''' <remarks>A note</remarks>
    <System.Serializable()> Private Class Note
        'The note header
        Public Header As String

        'The note content
        Public Content As String

        'The time this note will occur
        Public Time As Date

        'The priority of the note
        Public Priority As Priority

        'The warnings of the note, this is when and how the user will be alerted
        Public Warning As Warning

        ''' <summary>
        ''' Create a new note
        ''' </summary>
        ''' <param name="h">The note header</param>
        ''' <param name="c">The note content</param>
        ''' <param name="t">The time this note will occur</param>
        ''' <param name="p">The priority of the note</param>
        ''' <param name="w">The warnings of the note, this is when and how the user will be alerted</param>
        ''' <remarks>Create a new note</remarks>
        Public Sub New(ByVal h As String, ByVal c As String, ByVal t As Date, ByVal p As Priority, ByVal w As Warning)
            Header = h
            Content = c
            Time = t
            Priority = p
            Warning = w
        End Sub

        ''' <summary>
        ''' Returns a clone of the current note
        ''' </summary>
        ''' <returns>Returns a clone of the current note</returns>
        ''' <remarks>Returns a clone of the current note</remarks>
        Public Function Clone() As Note
            Return New Note(Header, Content, Time, Priority, Warning)
        End Function


    End Class


    ''' <summary>
    ''' Used by the note class
    ''' </summary>
    ''' <remarks>Used by the note class</remarks>
    Public Class Priority
        'The priority type, this is what's controling the priority.
        Private myType As PriorityType

        'The color to use when drawing the priority
        Private myColor As Brush

        'The font to use when drawing the priority
        Private myFont As Font

        ''' <summary>
        ''' Creates a new priority
        ''' </summary>
        ''' <param name="P">The priority type</param>
        ''' <remarks>Creates a new priority</remarks>
        Public Sub New(ByVal P As PriorityType)
            'Saves the type...
            myType = P
            '...and generate the styles acordingly
            GenerateStyles()
        End Sub

        ''' <summary>
        ''' The type of the priority
        ''' </summary>
        ''' <value>The type of the priority</value>
        ''' <returns>The type of the priority</returns>
        ''' <remarks>The type of the priority</remarks>
        Public ReadOnly Property Type() As PriorityType
            Get
                Return myType
            End Get
        End Property

        ''' <summary>
        ''' The color of the priority
        ''' </summary>
        ''' <value>The color of the priority</value>
        ''' <returns>The color of the priority</returns>
        ''' <remarks>The color of the priority</remarks>
        Public ReadOnly Property Color() As Brush
            Get
                Return myColor
            End Get
        End Property

        ''' <summary>
        ''' The font of the priority
        ''' </summary>
        ''' <value>The font of the priority</value>
        ''' <returns>The font of the priority</returns>
        ''' <remarks>The font of the priority</remarks>
        Public ReadOnly Property Font() As Font
            Get
                Return myFont
            End Get
        End Property

        ''' <summary>
        ''' Generate the styles depending on the type
        ''' </summary>
        ''' <remarks></remarks>
        Private Sub GenerateStyles()
            'Check the type of the priority
            Select Case myType.ToString
                Case "Note"
                    'Load the Note priority styles
                    myColor = Brushes.Black
                    myFont = New Font("Arial", 8, FontStyle.Regular, GraphicsUnit.Point)
                Case "Remember"
                    'Load the Remember priority styles
                    myColor = Brushes.Black
                    myFont = New Font("Arial", 8, FontStyle.Bold, GraphicsUnit.Point)
                Case "IMPORTANT"
                    'Load the IMPORTANT priority styles
                    myColor = Brushes.Red
                    myFont = New Font("Arial", 12, FontStyle.Bold, GraphicsUnit.Point)
            End Select
        End Sub


    End Class
    Public Enum PriorityType
        Note
        Remember
        IMPORTANT
    End Enum

    ''' <summary>
    ''' Used by the note class
    ''' </summary>
    ''' <remarks>Used by the note class</remarks>
    Public Class Warning
        'The warning type
        Private myType As WarningType
        'The warning time
        Private myTime As WarningTime

        ''' <summary>
        ''' Create a new warning
        ''' </summary>
        ''' <param name="Type">The warning type</param>
        ''' <param name="Time">The warning time</param>
        ''' <remarks>Create a new warning</remarks>
        Public Sub New(ByVal Type As WarningType, ByVal Time As WarningTime)
            myType = Type
            myTime = Time
        End Sub

        ''' <summary>
        ''' Return Warning Type
        ''' </summary>
        ''' <value>Return Warning Type</value>
        ''' <returns>Return Warning Type</returns>
        ''' <remarks>Return Warning Type</remarks>
        Public ReadOnly Property Type() As WarningType
            Get
                Return myType
            End Get
        End Property

        ''' <summary>
        ''' Return Warning Time
        ''' </summary>
        ''' <value>Return Warning Time</value>
        ''' <returns>Return Warning Time</returns>
        ''' <remarks>Return Warning Time</remarks>
        Public ReadOnly Property Time() As WarningTime
            Get
                Return myTime
            End Get
        End Property

    End Class
    Public Enum WarningType
        None
        Sound
        Text
        Sound_and_text 'little t in text so it will fit in the combobox, don't change it
    End Enum
    Public Enum WarningTime
        On_time
        _1_minute
        _5_minutes
        _15_minutes
        _30_minutes
        _1_hour
        _2_hours
        _1_day
        _2_days
        _3_days
        _1_week
    End Enum

#End Region


End Class
